/*
 * Copyright (C) 2021 Fastjrun, Inc. All Rights Reserved.
 */
package com.fastjrun.security.authentication;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fastjrun.security.properties.SecurityProperties;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

public class CustomAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

  @Resource private SecurityProperties securityProperties;

  public CustomAuthenticationFilter() {
    super(new AntPathRequestMatcher("/user/login", "POST"));
  }

  @Override
  public Authentication attemptAuthentication(
      HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    ObjectMapper mapper = new ObjectMapper();
    if (request.getMethod().equalsIgnoreCase("POST")
        && (request
            .getRequestURI()
            .endsWith(securityProperties.getAuthentication().getLoginUrl()))) {
      try (InputStream is = request.getInputStream()) {
        Map<String, String> authenticationBean = mapper.readValue(is, Map.class);
        UsernamePasswordAuthenticationToken authRequest =
            new UsernamePasswordAuthenticationToken(
                authenticationBean.get("username"), authenticationBean.get("password"));
        setDetails(request, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);
      } catch (IOException e) {
        e.printStackTrace();
        throw new AuthenticationServiceException("Authentication fail. ");
      }
    }
    return null;
  }

  /** 将 sessionID和hostname添加 到MobileAuthenticationToken */
  protected void setDetails(
      HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
    authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
  }
}
